﻿using MahApps.Metro.Controls;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
    /// <summary>
    /// PresentationWindow.xaml 的交互逻辑
    /// </summary>
    public partial class PresentationHtmlWindow : Window
    {
        public PresentationHtmlWindow(MarkdownEditor editor, List<string> htmlFilesList, List<string> mdFilesList)
        {
            InitializeComponent();

            //防止被任务栏覆盖或覆盖任务栏。
            //this.Top = 0;
            //this.Left = 0;
            //this.Height = this.MaxHeight = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Height;
            //this.Width = this.MaxWidth = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width;

            this.masterEditor = editor;
            this.htmlFilesList = htmlFilesList;
            this.mdFilesList = mdFilesList;

            this.Closed += Window_Closed;
            this.webBrowser.PreviewMouseWheel += WebBrowser_PreviewMouseWheel;
        }

        private void WebBrowser_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
            KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);
            //KeyStates ksLeftShift = Keyboard.GetKeyStates(Key.LeftShift);
            //KeyStates ksRightShift = Keyboard.GetKeyStates(Key.RightShift);
            //KeyStates ksLeftAlt = Keyboard.GetKeyStates(Key.LeftAlt);
            //KeyStates ksRightAlt = Keyboard.GetKeyStates(Key.RightAlt);
            //KeyStates ksLeftWin = Keyboard.GetKeyStates(Key.LWin);
            //KeyStates ksRightWin = Keyboard.GetKeyStates(Key.RWin);

            bool isCtrl = ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0);

            if (isCtrl)
            {
                e.Handled = true;//不能让浏览器自己滚动缩放

                webBrowser.Zoom += e.Delta * 10;
                App.ConfigManager.Set("Zoom", webBrowser.Zoom.ToString());
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            try
            {
                //删除添加的临时演示文件。
                foreach (var filePath in htmlFilesList) { if (File.Exists(filePath)) { File.Delete(filePath); } }
                foreach (var filePath in mdFilesList) { if (File.Exists(filePath)) { File.Delete(filePath); } }
            }
            catch (Exception ex)
            {
                LMessageBox.Show("发生意外，无法删除演示临时文件。错误消息如下：\r\n" + ex.Message, Globals.AppName,
                     MessageBoxButton.OK, MessageBoxImage.Warning, "", null, this);
            }
        }

        public List<Uri> UrisList { get; set; }

        private List<string> htmlFilesList;
        private List<string> mdFilesList;

        private MarkdownEditor masterEditor = null;

        public MarkdownEditor MasterEditor
        {
            get { return this.masterEditor; }
        }

        private int point;

        void numTextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var textBlock = sender as TextBlock;
            if (textBlock == null || textBlock.Tag == null) return;

        }

        private void btnNext_Click(object sender, RoutedEventArgs e)
        {
            if (this.point < this.UrisList.Count - 1)
            {
                this.point++;
                ShowPage();
                prompt.Text = "";
            }
            else
            {
                prompt.Text = "已至最后一页！";
                LMessageBox.Show("已至最后一页！", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning, "", null, this);
            }
        }

        private void btnPreview_Click(object sender, RoutedEventArgs e)
        {
            if (this.point > 0)
            {
                this.point--;
                ShowPage();
                prompt.Text = "";
            }
            else
            {
                prompt.Text = "已至第一页！";
                LMessageBox.Show("已至第一页！", Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning, "", null, this);
            }
        }

        private void ShowPage()
        {
            this.askPanel.Visibility = Visibility.Collapsed;//隐藏提问面板。

            if (point >= 0 && point < UrisList.Count)
            {
                this.webBrowser.ActiveXControl.Navigate2(UrisList[point].LocalPath);
            }

            this.pageNumber.Text = $"第 {point + 1} 页，共 {UrisList.Count} 页";
        }

        private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            KeyStates ksLeftCtrl = Keyboard.GetKeyStates(Key.LeftCtrl);
            KeyStates ksRightCtrl = Keyboard.GetKeyStates(Key.RightCtrl);
            KeyStates ksLeftShift = Keyboard.GetKeyStates(Key.LeftShift);
            KeyStates ksRightShift = Keyboard.GetKeyStates(Key.RightShift);
            KeyStates ksLeftAlt = Keyboard.GetKeyStates(Key.LeftAlt);
            KeyStates ksRightAlt = Keyboard.GetKeyStates(Key.RightAlt);
            KeyStates ksLeftWin = Keyboard.GetKeyStates(Key.LWin);
            KeyStates ksRightWin = Keyboard.GetKeyStates(Key.RWin);

            bool isCtrl = ((ksLeftCtrl & KeyStates.Down) > 0 || (ksRightCtrl & KeyStates.Down) > 0);

            //数字键1到9，表示选择学生名册中第几批次（可以将一个班级分为几批）
            if (e.Key >= Key.D1 && e.Key <= Key.D9)
            {
                int index = e.Key - Key.D1;
                if (index < 0) index = 0;

                if (index > cmboxStudentsListFilenames.Items.Count - 1) index = cmboxStudentsListFilenames.Items.Count - 1;

                if (index >= 0 && index <= cmboxStudentsListFilenames.Items.Count - 1)
                {
                    cmboxStudentsListFilenames.SelectedIndex = index;
                }
                //如果索引越界，不起任何作用。
            }

            if (!isCtrl)
            {
                if (e.Key == Key.Up)
                {
                    mshtml.HTMLDocument htmlDoc = webBrowser.ActiveXControl.Document as mshtml.HTMLDocument;
                    int currentPosion = htmlDoc.getElementsByTagName("HTML").item(null, 0).ScrollTop;
                    htmlDoc.parentWindow.scrollTo(0, currentPosion - 40);

                    e.Handled = true;
                    return;
                }

                if (e.Key == Key.Down)
                {
                    mshtml.HTMLDocument htmlDoc = webBrowser.ActiveXControl.Document as mshtml.HTMLDocument;
                    int currentPosion = htmlDoc.getElementsByTagName("HTML").item(null, 0).ScrollTop;
                    htmlDoc.parentWindow.scrollTo(0, currentPosion + 40);

                    e.Handled = true;
                    return;
                }

                if (e.Key == Key.Left || e.Key == Key.OemComma || e.Key == Key.OemOpenBrackets || e.Key == Key.OemMinus || e.Key == Key.Prior)//Prior,即PageUp
                {
                    btnPreview_Click(sender, e);
                    e.Handled = true;
                    return;
                }

                if (e.Key == Key.Right || e.Key == Key.OemPeriod || e.Key == Key.OemCloseBrackets || e.Key == Key.OemPlus || e.Key == Key.PageDown)//Prior,即PageUp
                {
                    btnNext_Click(sender, e);
                    e.Handled = true;
                    return;
                }

                if (e.Key == Key.Escape || e.Key == Key.X)
                {
                    if (this.askPanel.Visibility == Visibility.Visible)
                    {
                        this.askPanel.Visibility = Visibility.Collapsed;//隐藏提问面板。
                        e.Handled = true;
                        return;
                    }

                    this.Close();
                    return;
                }

                //Tab键用于提问。
                if (e.Key == Key.Tab)
                {
                    AskSomeoneAQuestion();
                    e.Handled = true;
                    return;
                }
            }
            else
            {
                if (e.Key == Key.OemMinus)
                {
                    //Ctrl+-
                    slider1.Value -= 10;
                    slider1_DragCompleted(sender, e);
                    e.Handled = true;
                    return;
                }

                if (e.Key == Key.OemPlus)
                {
                    //Ctrl++
                    slider1.Value += 10;
                    slider1_DragCompleted(sender, e);
                    e.Handled = true;
                    return;
                }
            }
        }

        public static DependencyObject GetScrollViewer(DependencyObject o)
        {
            // Return the DependencyObject if it is a ScrollViewer
            if (o is ScrollViewer)
            { return o; }

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
            {
                var child = VisualTreeHelper.GetChild(o, i);

                var result = GetScrollViewer(child);
                if (result == null)
                {
                    continue;
                }
                else
                {
                    return result;
                }
            }

            return null;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            #region 载入学生名册列表
            try
            {
                cmboxStudentsListFilenames.Items.Clear();

                string studentListDirectoryPath = Globals.PathOfUserFolder + (Globals.PathOfUserFolder.EndsWith("\\") ? "" : "\\") + "StudentsLists\\";
                if (Directory.Exists(studentListDirectoryPath) == false)
                {
                    Directory.CreateDirectory(studentListDirectoryPath);
                }

                DirectoryInfo studentListDirectoryinfo = new DirectoryInfo(studentListDirectoryPath);
                FileInfo[] childFiles = studentListDirectoryinfo.GetFiles();

                if (childFiles.Count<FileInfo>() <= 0)
                {
                    var sampleClassFilePath = studentListDirectoryPath + "SampleClass.txt";
                    if (File.Exists(sampleClassFilePath) == false)
                    {
                        File.WriteAllText(sampleClassFilePath, Properties.Resources.SampleClassFileContent);
                    }
                }

                var directoryInfo = new DirectoryInfo(studentListDirectoryPath);
                var fileInfos = directoryInfo.GetFiles();

                foreach (var fi in fileInfos)
                {
                    cmboxStudentsListFilenames.Items.Add(new ComboBoxItem() { Content = fi.Name, });
                }

                var selectedStudentListShortFileName = App.ConfigManager.Get("SelectedStudentListShortFileName");
                if (selectedStudentListShortFileName != null && selectedStudentListShortFileName != string.Empty)
                {
                    ComboBoxItem cbi = null;
                    foreach (var i in cmboxStudentsListFilenames.Items)
                    {
                        var ii = i as ComboBoxItem;
                        if (ii == null) continue;

                        if (ii.Content.ToString() == selectedStudentListShortFileName)
                        {
                            cbi = ii;
                            break;
                        }
                    }

                    if (cbi != null)
                    {
                        var newIndex = cmboxStudentsListFilenames.Items.IndexOf(cbi);
                        cmboxStudentsListFilenames.SelectedIndex = newIndex;
                    }
                    else
                    {
                        if (cmboxStudentsListFilenames.Items.Count > 0)
                        {
                            cmboxStudentsListFilenames.SelectedIndex = 0;
                        }
                    }
                }
                else
                {
                    if (cmboxStudentsListFilenames.Items.Count > 0)
                    {
                        cmboxStudentsListFilenames.SelectedIndex = 0;
                    }
                }
            }
            catch (Exception ex)
            {
                LMessageBox.Show(ex.Message, Globals.AppName, MessageBoxButton.OK, MessageBoxImage.None, "", null, this);
            }
            #endregion 载入学生名册

            //载入Zoom
            var zoomText = App.ConfigManager.Get("Zoom");
            if (string.IsNullOrWhiteSpace(zoomText) == false)
            {
                int zoom;
                if (int.TryParse(zoomText, out zoom))
                {
                    webBrowser.Zoom = zoom;
                }
                else webBrowser.Zoom = 100;
            }
            else webBrowser.Zoom = 100;

            Globals.SwitchInputMethod(false);

            this.InvalidateVisual();

            if (this.UrisList.Count > 0)
            {
                this.point = 0;
                this.ShowPage();
            }
        }

        private void Window_Activated(object sender, EventArgs e)
        {
            Globals.SwitchInputMethod(false);
        }

        private void AskSomeoneAQuestion()
        {
            var student = this.GetAStudent();
            if (student == null)
            {
                tbkStudentName.Text = "<未设置名册>";
            }
            else
            {
                tbkStudentName.Text = student.Number + "号 " + student.Name;
            }

            askPanel.Visibility = System.Windows.Visibility.Visible;
        }

        private void btnAskRandom_Click(object sender, RoutedEventArgs e)
        {
            this.AskSomeoneAQuestion();
        }

        private void cmboxStudentsListFilenames_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var selItem = cmboxStudentsListFilenames.SelectedItem as ComboBoxItem;
            if (selItem == null) return;

            string fileShortName = selItem.Content as string;
            if (string.IsNullOrEmpty(fileShortName)) return;

            ReadStudentsFromFile(fileShortName);
        }

        private List<Student> students;

        private void ReadStudentsFromFile(string fileShortName)
        {
            if (students == null)
            {
                students = new List<Student>();
            }
            students.Clear();

            if (string.IsNullOrEmpty(fileShortName))
            {
                return;
            }
            //先看文件在何处。

            string studentListFileFullPath = Globals.PathOfUserFolder + (Globals.PathOfUserFolder.EndsWith("\\") ? "" : "\\") + "StudentsLists\\" + fileShortName;
            if (File.Exists(studentListFileFullPath))
            {
                using (StreamReader sr = new StreamReader(studentListFileFullPath))
                {
                    while (!sr.EndOfStream) //读到结尾退出
                    {
                        string strLine = sr.ReadLine(); strLine = strLine.Trim();

                        if (strLine.Length == 0) continue;

                        if (strLine.StartsWith("//")) continue;//这个用作备注。

                        if (strLine.Contains("//"))
                        {
                            strLine = strLine.Substring(0, strLine.IndexOf("//"));
                        }

                        if (string.IsNullOrEmpty(strLine)) continue;

                        //将每一行拆分，分隔符就是char 数组中的字符
                        string[] stringPieces = strLine.Split(new char[] { '\t', ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
                        //将拆分好的string[] 存入list
                        if (stringPieces.Length == 2)
                        {
                            students.Add(new Student() { Name = stringPieces[1], Number = stringPieces[0], });
                        }

                    }
                }
            }

            RandomStudents();
        }

        private void RandomStudents()
        {
            if (studentPoint >= students.Count)
            {
                studentPoint = 0;
            }

            //混淆。
            int[] random = L.GetRandomIntArray(students.Count);
            foreach (int i in random)
            {
                students[i].OrderNumber = random[i];
            }
            students.Sort(new CmparsionStudent());

        }

        private int studentPoint = 0;

        private Student GetAStudent()
        {
            if (students == null || students.Count <= 0) return null;

            var student = students[studentPoint];

            studentPoint++;

            //重新混淆一次。
            if (studentPoint >= students.Count)
            {
                RandomStudents();
                studentPoint = 0;
            }

            return student;
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //在配置文件中存储当前使用的学生名册
            if (cmboxStudentsListFilenames.SelectedItem != null)
            {
                var cbi = cmboxStudentsListFilenames.SelectedItem as ComboBoxItem;
                if (cbi != null)
                {
                    App.ConfigManager.Set("SelectedStudentListShortFileName", cbi.Content.ToString());
                }
            }
        }

        private void slider1_DragCompleted(object sender, RoutedEventArgs e)
        {
            this.webBrowser.Zoom = (int)slider1.Value;
            App.ConfigManager.Set("Zoom", this.webBrowser.Zoom.ToString());
        }
    }
}
